package cn.tedu.charging.order.service.impl;

import cn.tedu.charging.common.constant.MqttTopicConst;
import cn.tedu.charging.common.pojo.message.StartCheckMessage;
import cn.tedu.charging.common.pojo.param.OrderAddParam;
import cn.tedu.charging.common.protocol.JsonResult;
import cn.tedu.charging.common.utils.SnowflakeIdGenerator;
import cn.tedu.charging.order.clients.DeviceClient;
import cn.tedu.charging.order.clients.UserClient;
import cn.tedu.charging.order.mqtt.MqttProducer;
import cn.tedu.charging.order.service.OrderService;
import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class OrderServiceImpl implements OrderService {
    @Autowired
    private DeviceClient deviceClient;
    @Autowired
    private UserClient userClient;
    @Autowired
    private SnowflakeIdGenerator snowflakeIdGenerator;
    @Autowired
    private MqttProducer mqttProducer;
    @Override
    public String createOrder(OrderAddParam param) {
        //1.检查设备---轻做
        checkGunAvailable(param.getGunId());
        // 2.检车车主或者车辆--轻做
        checkUserAvailable(param.getUserId(),param.getGunId());
        //3.生成订单编号
        String billId=snowflakeIdGenerator.nextId()+"";
        //4.和设备通信,发送开始充电命令
        //4.1组织一个消息对象 StartCheckMessage
        StartCheckMessage message=new StartCheckMessage();
        message.setOrderNo(billId);
        message.setUserId(param.getUserId());
        message.setGunId(param.getGunId());
        String msg= JSON.toJSONString( message);
        //4.2发送消息
        mqttProducer.send(
                MqttTopicConst.START_GUN_CHECK_PREFIX+param.getPileId(),msg);
        //TODO 5.发送延迟消息 防止设备没有响应
        //TODO 6.修改枪状态
        //TODO 7.计算该订单的最长执行充电时间 发布定时任务
        return billId;
    }

    private void checkUserAvailable(Integer userId, Integer gunId) {
        //1.调用车主服务
        JsonResult<Boolean> result=userClient.checkUserGun(userId,gunId);
        //2.解析结果
        Boolean available=result.getData();
        if (available){
            log.debug("车主检查枪可用,userId={},gunId={}",userId,gunId);
        }else{
            log.debug("车主检查枪不可用,userId={},gunId={}",userId,gunId);
            throw new RuntimeException("车主不可使用该枪充电");
        }
    }

    private void checkGunAvailable(Integer gunId) {
        //1.调用deviceClient
        JsonResult<Boolean> result=deviceClient.checkGun(gunId);
        //2.解析结果
        Boolean available=result.getData();
        if (available){
            log.debug("设备检查枪可用,gunId={}",gunId);
        }else{
            log.debug("设备检查枪不可用,gunId={}",gunId);
            throw new RuntimeException("设备检查枪不可用");
        }
    }
}
